package com.fancy.common.spi.proxy;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.ProxySelector;
import java.net.SocketAddress;
import java.net.URI;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Lists;

/**
 * 系统代理配置类（翻墙神器）
 * 
 * @author xinfeng.hu 2013-3-13下午12:15:34
 * @version 1.0.0
 * @category 杭州广桥网络技术有限公司(商业先知)
 */
public class DefaultProxySelector extends ProxySelector {

	/**
	 * 日志记录器
	 */
	private static final Logger logger = LoggerFactory.getLogger(DefaultProxySelector.class);

	/**
	 * 国外主机代理
	 */
	private static final List<Proxy> ABROAD_PROXY_LIST;

	/**
	 * 直接连接
	 */
	private static final List<Proxy> DIRECT_PROXY_LIST;

	static {

		// 国外主机代理
		SocketAddress socket = InetSocketAddress.createUnresolved("173.255.217.123", 3229);
		ABROAD_PROXY_LIST = Lists.newArrayList(new Proxy(Proxy.Type.HTTP, socket));

		// 直接连接
		DIRECT_PROXY_LIST = Lists.newArrayList(Proxy.NO_PROXY);
	}

	/**
	 * 代理连接选择器
	 */
	public List<Proxy> select(URI uri) {

		if (uri == null) {
			logger.error("select param error.");
			throw new IllegalArgumentException("URI can't be null.");
		}

		String protocol = uri.getScheme();
		String host = uri.getHost();
		if (host == null) {
			String auth = uri.getAuthority();
			if (auth != null) {
				int i;
				i = auth.indexOf('@');
				if (i >= 0) {
					auth = auth.substring(i + 1);
				}
				i = auth.lastIndexOf(':');
				if (i >= 0) {
					auth = auth.substring(0, i);
				}
				host = auth;
			}
		}

		if (protocol == null || host == null) {
			logger.error("protocol = " + protocol + " host = " + host);
			throw new IllegalArgumentException("protocol = " + protocol + " host = " + host);
		}

		host = host.toLowerCase();
		protocol = protocol.toLowerCase();

		// 只代理HTTP
		if (protocol.equals("http")) {
			if (host.indexOf("google") >= 0) {
				// Google 使用翻墙神器
				logger.debug("use abroad proxy,host={}", host);
				return ABROAD_PROXY_LIST;
			}
		}

		// 其余都直接连接
		return DIRECT_PROXY_LIST;
	}

	/**
	 * 代理连接错误后的处理【直接连接】
	 */
	public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
		if (uri == null || sa == null || ioe == null) {
			throw new IllegalArgumentException("Arguments can't be null.");
		}
	}

}
